package com.ihr360.expr.engine;

import com.ihr360.expr.parser.ExprToken;

import java.util.StringJoiner;

/**
 * 实体变量
 */
public class VariableID extends SimpleVariableID implements Comparable<VariableID> {
    private final static String NS_FIELD_CONNECTOR = ExprToken.NS_FIELD_CONNECTOR.val;
    public final static String SHEET_NS_CONNECTOR = "!";
    private final static String SYS_OR_COM_MARKER = ExprToken.NS_FIELD_CONNECTOR.val;
    private String sheet;
    private String namespace;
    private String field;
    public VariableID(String variableId) {
        this.variableId = variableId;

        int sheetIndex = variableId.indexOf(SHEET_NS_CONNECTOR);
        if (sheetIndex != -1 && sheetIndex != 0 && sheetIndex != variableId.length() - 1) {
            this.sheet = variableId.substring(0, sheetIndex);
            variableId = variableId.substring(sheetIndex + 1, variableId.length());
        }
        if (variableId.startsWith(SYS_OR_COM_MARKER)) {
            int index = variableId.lastIndexOf(NS_FIELD_CONNECTOR);
            if (index != -1 && index != 0 && index != variableId.length() - 1) {
                this.namespace = variableId.substring(0, index);
                this.field = variableId.substring(index + 1, variableId.length());
            }
        } else {
            int index = variableId.indexOf(NS_FIELD_CONNECTOR);
            if (index != -1 && index != 0 && index != variableId.length() - 1) {
                this.namespace = variableId.substring(0, index);
                this.field = variableId.substring(index + 1, variableId.length());
            }else{
                this.field = variableId;
            }
        }

    }

    private VariableID(String namespace, String field) {
        this.namespace = namespace;
        this.field = field;
        if (namespace != null && namespace.trim().length() > 0) {
            StringJoiner joiner = new StringJoiner(NS_FIELD_CONNECTOR);
            joiner.add(namespace);
            joiner.add(field);
            this.variableId = joiner.toString();
        } else {
            this.variableId = field;
        }
    }

    public String getVariableId() {
        return variableId;
    }

    public static VariableID valueOf(String variableId) {
        return new VariableID(variableId);
    }

    public String getNamespace() {
        return namespace;
    }

    public boolean hasNamespece() {
        return namespace != null && namespace.length() > 0;
    }

    public boolean hasSheet(){
        return sheet != null && sheet.length() > 0;
    }

    public String getSheet() {
        return sheet;
    }

    public String getField() {
        if (field == null) {
            return this.variableId;
        }
        return field;
    }

    public void setDisplayName(String displayName) {
        this.displayName = displayName;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        VariableID that = (VariableID) o;

        return !(variableId != null ? !variableId.equals(that.variableId) : that.variableId != null);

    }

    public static boolean hasSheet(String variableId) {
        int sheetIndex = variableId.indexOf(SHEET_NS_CONNECTOR);
        if (sheetIndex != -1 && sheetIndex != 0 && sheetIndex != variableId.length() - 1) {
            return true;
        }
        return false;
    }

    public static boolean isPhasedSheet(String variableId){
        return hasSheet(variableId) && variableId.startsWith("PHASE");
    }

    public static VariableID build(String namespace, String field) {
        return new VariableID(namespace, field);
    }


    public static String buildVariableWithSheetIdAndFieldId(String sheet, String field) {
        StringJoiner joiner = new StringJoiner(SHEET_NS_CONNECTOR);
        joiner.add(sheet);
        joiner.add(field);
        return joiner.toString();
    }

    public static String buildVariableId(String namespace, String field) {
        if (namespace == null || namespace.trim().length() == 0) {
            return field;
        }
        StringJoiner joiner = new StringJoiner(NS_FIELD_CONNECTOR);
        joiner.add(namespace);
        joiner.add(field);
        return joiner.toString();
    }

    public static String buildPhasedVariableId(String phase, String field) {
        if (phase == null || phase.trim().length() == 0) {
            return field;
        }
        StringJoiner joiner = new StringJoiner(SHEET_NS_CONNECTOR);
        joiner.add(phase);
        joiner.add(field);
        return joiner.toString();
    }

    public static String buildVariableId(String sheet, String namespace, String field) {
        if (sheet == null && sheet.length() > 0) {
            return buildVariableId(namespace, field);
        }
        StringBuilder builder = new StringBuilder();
        builder.append(sheet);
        builder.append(SHEET_NS_CONNECTOR);
        if (namespace != null && namespace.length() > 0) {
            builder.append(namespace);
            builder.append(NS_FIELD_CONNECTOR);
        }
        builder.append(field);
        return builder.toString();
    }

    @Override
    public int hashCode() {
        return variableId != null ? variableId.hashCode() : 0;
    }

    @Override
    public String toString() {
        return "VariableID{" +
                "namespace='" + namespace + '\'' +
                ", variableId='" + variableId + '\'' +
                '}';
    }

    @Override
    public int compareTo(VariableID o) {

        return this.variableId.compareTo(o.getVariableId());
    }
}